﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RXY_Mall.Application.Finance.Dto;
using RXY_Mall.Core;
using RXY_Mall.Core.Tool;
using RXY_Mall.Domain;
using System.Data.Entity;

namespace RXY_Mall.Application.Finance
{
    public class FinanceService : RXY_MallAppServiceBase, IFinanceService
    {
        public IList<SettlementDto> GetSettlementByPage(int iDisplayStart, int iDisplayLength, string dateMin, string dateMax, int status, string orderNo, int shopId, out int totalCount)
        {
            iDisplayLength = iDisplayLength < 1 ? 10 : iDisplayLength;
            DateTime dtMin = DateTime.MinValue;
            DateTime dtMax = DateTime.MaxValue;
            var list = db.gw_shop_finance_settlements
                .Where(u => u.shop_id == shopId&&u.type==1)
                .Select(item => new SettlementDto
                {
                    id = item.id,
                    shop_id=item.shop_id,
                    order_id = item.order_id,
                    order_type = item.goods_type,
                    order_no = item.order_no,
                    money = item.money,
                    order_total = item.order_total,
                    service_rate = item.service_rate,
                    account_period = item.account_period,
                    settlement_time = item.settlement_time,
                    status = item.status,
                    remark = item.remark,
                    add_time = item.add_time,
                    settlement_no = item.settlement_no
                });
            //list = list.ToList();
            if (status > -1)
            {
                list = list.Where(m => m.status == status);
            }
            if (!string.IsNullOrEmpty(orderNo))
            {
                list = list.Where(m => m.order_no.Contains(orderNo));
            }
            if (!string.IsNullOrWhiteSpace(dateMin))
            {
                dtMin = DateTime.Parse(dateMin);
            }
            if (!string.IsNullOrWhiteSpace(dateMax))
            {
                dtMax = DateTime.Parse(dateMax).Date.AddDays(1); ;
            }
            if (dateMin!=""|| dateMax!="")
            {
                list = list.Where(m => m.settlement_time >= dtMin && m.settlement_time <= dtMax);

            }
            totalCount = list.Count();
            list = list.OrderBy(m=>m.status).ThenByDescending(m => m.add_time).Skip(iDisplayStart).Take(iDisplayLength);
            return list.ToList();
        }
        public IList<FinanceLogDto> GetFinanceLogByPage(int iDisplayStart, int iDisplayLength, string dateMin, string dateMax, int type, int in_out, int shopId, out int totalCount)
        {
            int[] feeArr = { 21, 23 };
            iDisplayLength = iDisplayLength < 1 ? 10 : iDisplayLength;
            DateTime dtMin = DateTime.MinValue;
            DateTime dtMax = DateTime.MaxValue;
            var list = db.gw_shop_finance_logs
                .Where(u => u.shop_id == shopId&& !feeArr.Contains(u.trade_type))
                .Select(item => new FinanceLogDto
                {
                    id = item.id,
                    order_id = item.order_id,
                    relation_id = item.relation_id,
                    trade_type = item.trade_type,
                    in_out = item.in_out,
                    before = item.before,
                    end = item.end,
                    remark = item.remark,
                    add_time = item.add_time,
                    log_no = item.log_no,
                    order_no = item.order_no,
                    relation_no = item.relation_no,
                });
            if (type > -1)
            {
                if (type == 20)
                {
                    //int[] typeArr = { 20, 21, 22,23 };
                    int[] typeArr = { 20, 22 };
                    list = list.Where(m => typeArr.Contains(m.trade_type));

                }
                //else if (type == 30)
                //{
                //    int[] typeArr = {30,31};
                //    list = list.Where(m => typeArr.Contains(m.trade_type));

                //}
                else
                {
                    list = list.Where(m => m.trade_type == type);
                }
            }
            if (in_out>0)
            {
                list = list.Where(m => m.in_out==in_out);
            }
            if (!string.IsNullOrWhiteSpace(dateMin))
            {
                dtMin = DateTime.Parse(dateMin);
            }
            if (!string.IsNullOrWhiteSpace(dateMax))
            {
                dtMax = DateTime.Parse(dateMax).Date.AddDays(1); ;
            }
            list = list.Where(m => m.add_time >= dtMin && m.add_time <= dtMax);
            totalCount = list.Count();
            list = list.OrderByDescending(m => m.add_time).Skip(iDisplayStart).Take(iDisplayLength);
            var  dtoList = list.ToList();
            foreach (var item in dtoList)
            {
                if (item.trade_type==20||item.trade_type==22)
                {
                    var model = db.gw_shop_finance_withdrawals.FirstOrDefault(i => i.id == item.relation_id);
                    if (model!=null)
                    {
                        item.withdrawal_card_no = model.bank_name+"（"+(model.bank_cardno.Length>4? model.bank_cardno.Substring(model.bank_cardno .Length- 4): model.bank_cardno) +"）";
                    }
                }
            }
            return dtoList;
        }
        public IList<FinanceReturnDto> GetFinanceReturnByPage(int iDisplayStart, int iDisplayLength, string dateMin, string dateMax, int type, int shopId, out int totalCount)
        {
            iDisplayLength = iDisplayLength < 1 ? 10 : iDisplayLength;
            DateTime dtMin = DateTime.MinValue;
            DateTime dtMax = DateTime.MaxValue;
            var list = db.gw_shop_finance_returns
                .Where(u => u.shop_id == shopId)
                .Select(item => new FinanceReturnDto
                {
                    id = item.id,
                    shop_id=item.shop_id,
                    return_no = item.return_no,
                    order_id = item.order_id,
                    order_no = item.order_no,
                    money = item.money,
                    handing_time = item.handing_time,
                    type = item.type,
                    status=item.status,
                    remark = item.remark,
                    add_time = item.add_time,
                    settlement_no = item.settlement_no,
                    settlement_id = item.settlement_id,
                });
            if (type > -1)
            {
                list = list.Where(m => m.type == type);
            }
            if (!string.IsNullOrWhiteSpace(dateMin))
            {
                dtMin = DateTime.Parse(dateMin);
            }
            if (!string.IsNullOrWhiteSpace(dateMax))
            {
                dtMax = DateTime.Parse(dateMax).Date.AddDays(1); ;
            }
            list = list.Where(m => m.add_time >= dtMin && m.add_time <= dtMax);
            totalCount = list.Count();
            list = list.OrderByDescending(m => m.add_time).Skip(iDisplayStart).Take(iDisplayLength);
            return list.ToList();
        }
        public SettlementDto GetSettlementById(int id)
        {
            var model = db.gw_shop_finance_settlements.Where(i => i.id == id)
                .Select(item => new SettlementDto
                {
                    id = item.id,
                    shop_id=item.shop_id,
                    order_id = item.order_id,
                    order_type=item.goods_type,
                    order_no = item.order_no,
                    money = item.money,
                    order_total = item.order_total,
                    service_rate = item.service_rate,
                    account_period = item.account_period,
                    settlement_time = item.settlement_time,
                    status = item.status,
                    remark = item.remark,
                    add_time = item.add_time,
                    settlement_no = item.settlement_no
                }).FirstOrDefault();
            return model;
        }
        public FinanceLogDto GetFinanceLogById(int id)
        {
            var model = db.gw_shop_finance_logs.Where(i => i.id == id)
                .Select(item => new FinanceLogDto
                {
                    id = item.id,
                    shop_id=item.shop_id,
                    order_id = item.order_id,
                    relation_id = item.relation_id,
                    trade_type = item.trade_type,
                    in_out = item.in_out,
                    before = item.before,
                    end = item.end,
                    remark = item.remark,
                    add_time = item.add_time,
                    log_no = item.log_no,
                    order_no = item.order_no,
                    relation_no = item.relation_no,
                }).FirstOrDefault();
            return model;
        }
        public FinanceReturnDto GetFinanceReturnById(int id)
        {
            var model = db.gw_shop_finance_returns.Where(i => i.id == id)
                .Select(item => new FinanceReturnDto
                {
                    id = item.id,
                    shop_id=item.shop_id,
                    return_no= item.return_no,
                    order_id = item.order_id,
                    order_no = item.order_no,
                    money = item.money,
                    handing_time = item.handing_time,
                    type = item.type,
                    status = item.status,
                    remark = item.remark,
                    add_time = item.add_time,
                    settlement_no = item.settlement_no,
                    settlement_id = item.settlement_id,
                }).FirstOrDefault();
            return model;
        }
        public async Task SettlementCheck(int shopId = 0)
        {
            //int t = (int)GetParam(3);
            //var checkDate = DateTime.Now.AddDays(-t);
            var checkDate = DateTime.Now;
            var checking = db.gw_shop_finance_settlements.Include(i => i.gw_shop).Include(i => i.gw_shop.gw_shop_property).Where(i => i.status == 1 && i.type == 1 && i.add_time < checkDate);

            if (checking.Count() > 0)
            {
                foreach (var item in checking)
                {
                    //var shop = db.gw_shop_propertys.FirstOrDefault(i => i.id == item.shop_id);
                    if (item.gw_shop == null || item.gw_shop.gw_shop_property == null)
                    {
                        item.status = 7;
                        item.remark += "店铺信息异常";
                    }
                    else
                    {
                        //var money = item.order_total - item.order_total * item.service_rate / 100;
                        //money = Math.Round(money, 2, MidpointRounding.AwayFromZero);
                        //if (item.money <= 0 || item.money > money)
                        var hasError = false;
                        if (item.money <= 0)
                        {
                            var order_goods = db.gw_orders
                                   .Include(o => o.gw_order_goods)
                                   .FirstOrDefault(o => o.id == item.order_id);
                            if (order_goods != null && order_goods.gw_order_goods != null)
                            {
                                if (order_goods.gw_order_goods.FirstOrDefault().settlement_price > 0)
                                {
                                    item.money = (decimal)order_goods.gw_order_goods.FirstOrDefault().settlement_price * order_goods.gw_order_goods.FirstOrDefault().quantity;
                                }
                                else if(order_goods.gw_order_goods.FirstOrDefault().goods_type ==1&& order_goods.gw_order_goods.FirstOrDefault().service_rate >0)
                                {
                                    var money = item.order_total - item.order_total * item.service_rate / 100;
                                    money = Math.Round(money, 2, MidpointRounding.AwayFromZero);
                                    item.money = money;
                                }
                                else
                                {
                                    hasError = true;
                                }
                            }
                        }
                        if (hasError)
                        {
                            item.status = 9;
                            item.remark = "结算金额异常";
                        }
                        else
                        {
                            item.status = 2;
                            item.remark = "正在结算|";
                        }
                        
                    }
                }
                await db.SaveChangesAsync();
            }

        }
        public async Task SettlementDeal(int shopId = 0)
        {
            //TODO:加锁
            var dealing = db.gw_shop_finance_settlements.Include(i => i.gw_shop).Include(i => i.gw_shop.gw_shop_property).Where(i => i.status == 2 && i.type == 1).ToList();
            //int t = (int)GetParam(3);
            if (dealing.Count() > 0)
            {
                foreach (var item in dealing)
                {
                    //var shop = db.gw_shop_propertys.FirstOrDefault(i => i.id == item.shop_id);
                    if (item.gw_shop == null || item.gw_shop.gw_shop_property == null)
                    {
                        item.status = 7;
                        item.remark += "店铺信息异常|";
                    }
                    else
                    {
                        //var settleDate = item.add_time.AddDays(t).AddDays(item.account_period);
                        var settleDate = item.add_time.AddDays(item.account_period);
                        if (settleDate < DateTime.Now)
                        {
                            //var money = item.order_total - item.order_total * item.service_rate / 100;
                            //money = Math.Round(money, 2, MidpointRounding.AwayFromZero);
                            //if (item.money <= 0 || item.money > money)
                            var hasError = false;
                            if (item.money <= 0)
                            {
                                //item.money = money;
                                var order_goods = db.gw_orders
                                       .Include(o => o.gw_order_goods)
                                       .FirstOrDefault(o => o.id == item.order_id);
                                if (order_goods != null && order_goods.gw_order_goods != null)
                                {
                                    if (order_goods.gw_order_goods.FirstOrDefault().settlement_price > 0)
                                    {
                                        item.money = (decimal)order_goods.gw_order_goods.FirstOrDefault().settlement_price * order_goods.gw_order_goods.FirstOrDefault().quantity;
                                    }
                                    else if (order_goods.gw_order_goods.FirstOrDefault().goods_type == 1 && order_goods.gw_order_goods.FirstOrDefault().service_rate > 0)
                                    {
                                        var money = item.order_total - item.order_total * item.service_rate / 100;
                                        money = Math.Round(money, 2, MidpointRounding.AwayFromZero);
                                        item.money = money;
                                    }
                                    else
                                    {
                                        hasError = true;
                                    }
                                }
                            }
                            if (hasError)
                            {
                                item.status = 9;
                                item.remark = "结算金额异常";
                                item.settlement_time = DateTime.Now;
                            }
                            else
                            {
                                db.gw_shop_finance_logs.Add(new gw_shop_finance_log()
                                {
                                    shop_id = item.gw_shop.id,
                                    relation_id = item.id,
                                    trade_type = 30,
                                    currency = 1,
                                    in_out = 1,
                                    before = (decimal)item.gw_shop.gw_shop_property.balances,
                                    end = (decimal)item.gw_shop.gw_shop_property.balances + item.money,
                                    remark = "结算成功",
                                    add_time = DateTime.Now,
                                    order_no = item.order_no,
                                    relation_no = item.settlement_no,
                                    log_no = "FL" + DateTime.Now.ToString("yyMMddHHmmss") + RandomHelper.CreateRandomValue(6),
                                    order_id = item.order_id,
                                });
                                item.gw_shop.gw_shop_property.balances += item.money;
                                item.gw_shop.gw_shop_property.balance_settlement += item.money;

                                item.status = 6;
                                item.settlement_time = DateTime.Now;
                                item.remark = "结算成功";
                            }
                            
                        }
                    }
                }
                await db.SaveChangesAsync();
                await SettlementReturn();
            }
        }
        public async Task SettlementReturn(int shopId = 0)
        {
            //TODO: 加锁
            var returning = db.gw_shop_finance_settlements.Include(i => i.gw_shop).Include(i => i.gw_shop.gw_shop_property).Where(i => i.status == 4 && i.type == 2);
            if (returning.Count() > 0)
            {
                foreach (var item in returning)
                {
                    //var shop = db.gw_shop_propertys.FirstOrDefault(i => i.id == item.shop_id);
                    if (item.gw_shop == null || item.gw_shop.gw_shop_property == null)
                    {
                        item.status = 7;
                        item.remark += "店铺信息异常|";
                    }
                    else
                    {
                        //var money = item.order_total - item.order_total * item.service_rate / 100;
                        //money = Math.Round(money, 2, MidpointRounding.AwayFromZero);
                        //if (item.money <= 0 || item.money > money)
                        var hasError = false;
                        if (item.money <= 0)
                        {
                            //item.money = money;
                            var order_goods = db.gw_orders
                                   .Include(o => o.gw_order_goods)
                                   .FirstOrDefault(o => o.id == item.order_id);
                            if (order_goods != null && order_goods.gw_order_goods != null)
                            {
                                if (order_goods.gw_order_goods.FirstOrDefault().settlement_price > 0)
                                {
                                    item.money = (decimal)order_goods.gw_order_goods.FirstOrDefault().settlement_price * order_goods.gw_order_goods.FirstOrDefault().quantity;
                                }
                                else if (order_goods.gw_order_goods.FirstOrDefault().goods_type == 1 && order_goods.gw_order_goods.FirstOrDefault().service_rate > 0)
                                {
                                    var money = item.order_total - item.order_total * item.service_rate / 100;
                                    money = Math.Round(money, 2, MidpointRounding.AwayFromZero);
                                    item.money = money;
                                }
                                else
                                {
                                    hasError = true;
                                }
                            }
                        }
                        if (item.money > 0&& !hasError)
                        {
                            var freeze = db.gw_shop_finance_returns.FirstOrDefault(i => i.settlement_id == item.id && i.status == 1 && i.type == 1);
                            var due = db.gw_shop_finance_returns.FirstOrDefault(i => i.settlement_id == item.id && i.status == 1 && i.type == 2);
                            if (freeze == null && due == null)
                            {
                                if (item.gw_shop.gw_shop_property.balances >= item.money)
                                {
                                    //扣款
                                    db.gw_shop_finance_logs.Add(new gw_shop_finance_log()
                                    {
                                        shop_id = item.gw_shop.id,
                                        relation_id = item.id,
                                        trade_type = 31,
                                        currency = 1,
                                        in_out = 2,
                                        before = (decimal)item.gw_shop.gw_shop_property.balances,
                                        end = (decimal)item.gw_shop.gw_shop_property.balances - item.money,
                                        remark = "退款成功",
                                        add_time = DateTime.Now,
                                        order_no = item.order_no,
                                        relation_no = item.settlement_no,
                                        log_no = "FL" + DateTime.Now.ToString("yyMMddHHmmss") + RandomHelper.CreateRandomValue(6),
                                        order_id = item.order_id,
                                    });
                                    item.gw_shop.gw_shop_property.balances -= item.money;
                                    item.status = 5;
                                    item.settlement_time = DateTime.Now;
                                    item.remark = "已退款，结算成功";
                                }
                                else
                                {
                                    var due_money = item.money - item.gw_shop.gw_shop_property.balances;
                                    //冻结
                                    if (item.gw_shop.gw_shop_property.balances > 0)
                                    {
                                        var freezeRecord = new gw_shop_finance_return()
                                        {
                                            shop_id = item.gw_shop.id,
                                            order_id = item.order_id,
                                            order_no = item.order_no,
                                            money = (decimal)item.gw_shop.gw_shop_property.balances,
                                            type = 1,
                                            status = 1,
                                            remark = "订单退款，余额不足冻结资金",
                                            add_time = DateTime.Now,
                                            settlement_id = item.id,
                                            settlement_no = item.settlement_no,
                                            return_no = "FR" + DateTime.Now.ToString("yyMMddHHmmss") + RandomHelper.CreateRandomValue(6),

                                        };
                                        db.gw_shop_finance_returns.Add(freezeRecord);
                                        item.gw_shop.gw_shop_property.balances -= freezeRecord.money;
                                        item.gw_shop.gw_shop_property.balance_freeze += freezeRecord.money;
                                    }
                                    //欠款
                                    if (due_money > 0)
                                    {
                                        var dueRecord = new gw_shop_finance_return()
                                        {
                                            shop_id = item.gw_shop.id,
                                            order_id = item.order_id,
                                            order_no = item.order_no,
                                            money = (decimal)due_money,
                                            type = 2,
                                            status = 1,
                                            remark = "订单退款，余额不足欠款资金",
                                            add_time = DateTime.Now,
                                            settlement_id = item.id,
                                            settlement_no = item.settlement_no,
                                            return_no = "FR" + DateTime.Now.ToString("yyMMddHHmmss") + RandomHelper.CreateRandomValue(6),

                                        };
                                        db.gw_shop_finance_returns.Add(dueRecord);
                                        item.gw_shop.gw_shop_property.balance_due += dueRecord.money;
                                    }
                                }
                            }
                            else
                            {
                                if (item.gw_shop.gw_shop_property.balances >= item.money)
                                {
                                    decimal returnMoney = 0;
                                    if (freeze != null)
                                    {
                                        returnMoney += freeze.money;
                                    }
                                    if (due != null)
                                    {
                                        returnMoney += due.money;
                                    }
                                    if (returnMoney == item.money)
                                    {
                                        if (freeze != null)
                                        {
                                            freeze.status = 2;
                                            freeze.handing_time = DateTime.Now;
                                            freeze.remark = "冻结资金解除，订单退款总金额：" + item.money;
                                            item.gw_shop.gw_shop_property.balance_freeze -= freeze.money;
                                        }
                                        if (due != null)
                                        {
                                            due.status = 2;
                                            due.handing_time = DateTime.Now;
                                            due.remark = "欠款已还，订单退款总金额：" + item.money;
                                            item.gw_shop.gw_shop_property.balance_due -= due.money;
                                        }

                                        db.gw_shop_finance_logs.Add(new gw_shop_finance_log()
                                        {
                                            shop_id = item.gw_shop.id,
                                            relation_id = item.id,
                                            trade_type = 31,
                                            currency = 1,
                                            in_out = 2,
                                            before = (decimal)item.gw_shop.gw_shop_property.balances,
                                            end = (decimal)item.gw_shop.gw_shop_property.balances - item.money,
                                            remark = "退款成功",
                                            add_time = DateTime.Now,
                                            order_no = item.order_no,
                                            relation_no = item.settlement_no,
                                            log_no = "FL" + DateTime.Now.ToString("yyMMddHHmmss") + RandomHelper.CreateRandomValue(6),
                                            order_id = item.order_id,
                                        });

                                        item.gw_shop.gw_shop_property.balances -= item.money - (freeze == null ? 0 : freeze.money);

                                        item.status = 5;
                                        item.remark = "已退款，结算成功";
                                        item.settlement_time = DateTime.Now;
                                    }
                                    else
                                    {
                                        item.status = 8;
                                        item.remark += "退款金额异常(退款金额 异于 冻结+余额)";
                                        item.settlement_time = DateTime.Now;
                                    }
                                }
                            }
                        }
                        else
                        {
                            item.status = 8;
                            item.remark = "退款金额异常(退款金额为0)";
                            item.settlement_time = DateTime.Now;
                        }
                    }
                }
                await db.SaveChangesAsync();
            }
        }

        public WithdrawalDto GetWithdrawalById(int id)
        {
            var model = db.gw_shop_finance_withdrawals.Where(i=>i.id==id)
                .Select(item => new WithdrawalDto
                {
                    id = item.id,
                    company_name = item.company_name,
                    money = item.money,
                    bank_name = item.bank_name,
                    bank_cardno = item.bank_cardno,
                    account_holder = item.account_holder,
                    fee_rate = item.fee_rate,
                    fee = item.fee,
                    status = item.status,
                    remark = item.remark,
                    add_time = item.add_time,
                    withdrawal_no = item.withdrawal_no,
                    handling_time = item.handling_time
                }).FirstOrDefault();
            return model;
        }
        public async Task<Response<bool>> ApplyWithdraw(int manageId, int shopId, decimal money, string password)
        {
            LogHelper.WriteLog(String.Format("管理员{0}所属店铺{1}提现金额为{2}", manageId, shopId, money));
            StringBuilder errorList = new StringBuilder();
            if (money < 100)
            {
                errorList.Append("提现金额不能小于100；</br>");
            }
            if (money >50000)
            {
                errorList.Append("单笔提现金额不能高于5万；</br>");
            }
            if (money % 100 != 0)
            {
                errorList.Append("提现金额必须是100的倍数；</br>");
            }
            if (string.IsNullOrEmpty(password))
            {
                errorList.Append("支付密码不能为空；</br>");
            }
            if (!string.IsNullOrWhiteSpace(errorList.ToString()))
            {
                return ReturnError<bool>(errorList.ToString());
            }
            var bankCard = db.gw_shop_bankcards.FirstOrDefault(i => i.shop_id == shopId);
            if (bankCard == null)
            {
                return ReturnError<bool>("请先设置提现账号！");
            }
            var shop = db.gw_shop_propertys.FirstOrDefault(i => i.id == shopId);
            if (shop == null)
            {
                return ReturnError<bool>("店铺信息异常！");
            }
            var rate = GetParam(2);
            var fee = money * rate / 100;
            if ((money + fee) > (shop.balances-shop.balance_due))
            {
                return ReturnError<bool>("可用余额不足！");
            }
            var pwd = db.gw_shop_passwords.FirstOrDefault(i => i.shop_id == shopId && i.type == 1);
            if (pwd == null)
            {
                return ReturnError<bool>("请先设置支付密码！");
            }
            if (SecureHelper.Get32Md5Str(password + pwd.solt, true) != pwd.password)
            {
                return ReturnError<bool>("支付密码错误");
            }

            var withdrawal = new gw_shop_finance_withdrawal()
            {
                shop_id = shopId,
                bankcard_id = bankCard.id,
                company_name = bankCard.company_name == null ? "" : bankCard.company_name,
                bank_name = bankCard.bank_name,
                bank_cardno = bankCard.bank_cardno,
                account_holder = bankCard.account_holder,
                money = money,
                fee_rate = rate,
                fee = fee,
                handling_id = 0,
                manager_id = manageId,
                add_time = DateTime.Now,
                status = 1,
                remark = "",
                withdrawal_no = "FW" + DateTime.Now.ToString("yyMMddHHmmss") + RandomHelper.CreateRandomValue(6),

            };
            var model = db.gw_shop_finance_withdrawals.Add(withdrawal);
            await db.SaveChangesAsync();
            fee = fee > 0 ? fee : 0;
            var record = new gw_shop_finance_log()
            {
                shop_id = shopId,
                relation_id = model.id,
                trade_type = 20,
                currency = 1,
                in_out = 2,
                before = (decimal)shop.balances,
                end = (decimal)shop.balances - money-fee,
                remark = "提现中",
                add_time = DateTime.Now,
                order_no = "",
                relation_no = model.withdrawal_no,
                log_no = "FL" + DateTime.Now.ToString("yyMMddHHmmss") + RandomHelper.CreateRandomValue(6),
            };
            db.gw_shop_finance_logs.Add(record);
            //TODO: 加锁
            shop.balances -= money;
            if (fee > 0)
            {
                //var recordFee = new gw_shop_finance_log()
                //{
                //    shop_id = shopId,
                //    relation_id = model.id,
                //    trade_type = 21,
                //    currency = 1,
                //    in_out = 2,
                //    before = (decimal)shop.balances,
                //    end = (decimal)shop.balances - fee,
                //    remark = "提现中",
                //    add_time = DateTime.Now,
                //    order_no = "",
                //    relation_no = model.withdrawal_no,
                //    log_no = "FL" + DateTime.Now.ToString("yyMMddHHmmss") + RandomHelper.CreateRandomValue(6),
                //};
                //db.gw_shop_finance_logs.Add(recordFee);
                shop.balances -= fee;
            }

            var result = await db.SaveChangesAsync();
            if (result > 0)
            {
                return ReturnSuccess<bool>(true);
            }
            else
            {
                return ReturnError<bool>("提交失败，请重试！");
            }
        }
        public IList<WithdrawalDto> GetWithdrawalByPage(int iDisplayStart, int iDisplayLength, string dateMin, string dateMax, string code, int status, int shopId, out int totalCount)
        {
            iDisplayLength = iDisplayLength < 1 ? 10 : iDisplayLength;
            DateTime dtMin = DateTime.MinValue;
            DateTime dtMax = DateTime.MaxValue;
            var list = db.gw_shop_finance_withdrawals
                .Where(u => u.shop_id == shopId)
                .Select(item => new WithdrawalDto
                {
                    id = item.id,
                    company_name = item.company_name,
                    money = item.money,
                    bank_name = item.bank_name,
                    bank_cardno = item.bank_cardno,
                    account_holder = item.account_holder,
                    fee_rate = item.fee_rate,
                    fee = item.fee,
                    status = item.status,
                    remark = item.remark,
                    add_time = item.add_time,
                    withdrawal_no = item.withdrawal_no,
                    handling_time=item.handling_time
                });
            if (status > -1)
            {
                list = list.Where(m => m.status == status);
            }
            if (!string.IsNullOrWhiteSpace(code))
            {
                list = list.Where(m => m.withdrawal_no.Contains(code));
            }
            if (!string.IsNullOrWhiteSpace(dateMin))
            {
                dtMin = DateTime.Parse(dateMin);
            }
            if (!string.IsNullOrWhiteSpace(dateMax))
            {
                dtMax = DateTime.Parse(dateMax).Date.AddDays(1); ;
            }
            list = list.Where(m => m.add_time >= dtMin && m.add_time <= dtMax);
            totalCount = list.Count();
            list = list.OrderBy(m => m.status).ThenByDescending(i=>i.add_time).Skip(iDisplayStart).Take(iDisplayLength);
            return list.ToList();
        }
        public decimal GetParam(int type)
        {
            //TODO:设置系统参数
            if (type == 1)//会员提现费率
            {
                return (decimal)0.1;
            }
            else if (type == 2)//商家提现费率
            {
                return (decimal)0;
            }
            else if (type == 3)//发货T日确认收货
            {
                return 7;
            }
            else
            {
                return 0;
            }
        }

        public decimal GetBalance(int shopId)
        {
            var model = db.gw_shop_propertys.FirstOrDefault(i => i.id == shopId);
            if (model == null)
            {
                return 0;
            }
            else
            {
                return (decimal)model.balances;
            }
        }

        public decimal GetWithdrawaling(int shopId)
        {
            var list = db.gw_shop_finance_withdrawals.Where(i => i.shop_id == shopId && i.status == 1).ToList();
            return list.Sum(i => i.money);
        }
        public decimal GetWithdrawal(int shopId)
        {
            var list = db.gw_shop_finance_withdrawals.Where(i => i.shop_id == shopId && i.status == 3).ToList();
            return list.Sum(i => i.money);
        }
        public decimal GetSettlementing(int shopId)
        {
            int[] arr = { 1, 2 };
            var list = db.gw_shop_finance_settlements.Where(i => i.shop_id == shopId && arr.Contains(i.status) && i.type == 1).ToList();
            return list.Sum(i => i.money);
        }

        //订单数
        public decimal GetOrdersNumber(int shopId, int status)
        {
            return db.gw_orders
                .Include(o=>o.gw_order_goods)
                .Where(i =>i.gw_order_goods.FirstOrDefault().shop_id == shopId&&i.status == status).Count();
        }
        //商品数量
        public decimal GetGoodsNumber(int shopId, int isPublish)
        {
            return db.gw_goods.Include(u => u.gw_goods_property).Where(i => i.shop_id == shopId && !i.deleted && i.gw_goods_property.published == isPublish).Count();
        }

        public ShopPropertyDto GetShopBalances(int shopId)
        {
            var model = db.gw_shop_propertys.FirstOrDefault(i => i.id == shopId);
            ShopPropertyDto result = new ShopPropertyDto();
            if (model != null)
            {
                result.id = model.id;
                result.goods_count = model.goods_count;
                result.order_count = model.order_count;
                result.deposit = (decimal)model.deposit;
                result.balances = (decimal)model.balances;
                result.balance_freeze = model.balance_freeze;
                result.balance_due = model.balance_due;
                result.balance_settlement = model.balance_settlement;
            }
            return result;
        }

        public OrderStatisticsDto GetOrderTotal(int shopId)
        {
            //var list = db.gw_order_payments
            //    .Include(o => o.gw_order)
            //    .Include(o => o.gw_order.gw_order_goods)
            //    .Where(o => o.gw_order.gw_order_goods.shop_id== shopId)
            var list = db.gw_orders
                .Include(o => o.gw_order_goods)
                .Where(o => o.gw_order_goods.FirstOrDefault().shop_id == shopId)
                .Select(item=>new {
                    id=item.id,
                    //order_status = item.gw_order.order_status,
                    complete_time = item.complete_time,
                    status = item.status,
                    //pay_amount = item.pay_amount,
                    pay_amount = item.goods_total,
                    add_time = item.add_time,
                });
            var orderList = list.ToList();

            var today = DateTime.Now.Date;
            var week = today.AddDays(1 - Convert.ToInt32(today.DayOfWeek)).Date;
            var month = today.AddDays(1 - Convert.ToInt32(today.Day)).Date;
            var year = today.AddMonths(1 - Convert.ToInt32(today.Month)).AddDays(1 - Convert.ToInt32(today.Day)).Date;
            var seven = today.AddDays(1 - 7).Date;
            var thirty = today.AddDays(1 - 30).Date;

            int[] statusArr = { 4,5,6,10};
            return new OrderStatisticsDto {
                today_order_total = orderList.Where(o => statusArr.Contains(o.status) && o.add_time > today).Sum(o => o.pay_amount),
                today_order_number = orderList.Count(o => statusArr.Contains(o.status) && o.add_time > today),
                today_order_money = orderList.Where(o =>o.status == 10&& o.complete_time > today).Sum(o => o.pay_amount),

                week_order_total = orderList.Where(o => statusArr.Contains(o.status) && o.add_time > week).Sum(o => o.pay_amount),
                week_order_number = orderList.Count(o => statusArr.Contains(o.status) && o.add_time > week),
                week_order_money = orderList.Where(o => o.status == 10 && o.complete_time > week).Sum(o => o.pay_amount),

                month_order_total = orderList.Where(o => statusArr.Contains(o.status) && o.add_time > month).Sum(o => o.pay_amount),
                month_order_number = orderList.Count(o => statusArr.Contains(o.status) && o.add_time > month),
                month_order_money = orderList.Where(o => o.status == 10 && o.complete_time > month).Sum(o => o.pay_amount),

                year_order_total = orderList.Where(o => statusArr.Contains(o.status) && o.add_time > year).Sum(o => o.pay_amount),
                year_order_number = orderList.Count(o => statusArr.Contains(o.status) && o.add_time > year),
                year_order_money = orderList.Where(o => o.status == 10 && o.complete_time > year).Sum(o => o.pay_amount),

                seven_order_total = orderList.Where(o => statusArr.Contains(o.status) && o.add_time > seven).Sum(o => o.pay_amount),
                seven_order_number = orderList.Count(o => statusArr.Contains(o.status) && o.add_time > seven),
                seven_order_money = orderList.Where(o => o.status == 10 && o.complete_time > seven).Sum(o => o.pay_amount),

                thirty_order_total = orderList.Where(o => statusArr.Contains(o.status) && o.add_time > thirty).Sum(o => o.pay_amount),
                thirty_order_number = orderList.Count(o => statusArr.Contains(o.status) && o.add_time > thirty),
                thirty_order_money = orderList.Where(o => o.status == 10 && o.complete_time > thirty).Sum(o => o.pay_amount),
            };

        }
    }
}
